'''
Created on Apr 25, 2012

@author: root
'''

# This class represents an individual hadoop configuration File
#import wx
from Base import Base
#from xml.etree.ElementTree import parse
import Queue
import threading
import shutil
import os
import hashlib

#import datetime

class FileOps(Base):
   
    goldDir = ""
    goldFilename = ""
    goldPath = ""
    remoteDir = "/usr/lib/gphd/hadoop/conf/"
    Nodes = []
    Log = []
    Users = []
    returnQueue = Queue.Queue()
    Properties = []
   
  
   
      
    def Push(self,Nodes,Users,localPath,remotePath):
       
        '''
        Push a Single File to Multiple Hosts
        '''
        
        self.SetUsers(Users)

        pushStatus = 0
        threadCount = 0
        fileName = (str(localPath).split('/'))[len(str(localPath).split('/'))-1]
        nodeStr = ""
        for node in Nodes:
            nodeStr += (","+node.hostName)
        nodeStr= nodeStr[1:]
        Threads = [] 
        
        print "    * Push Modified "+str(fileName)+" file to " + nodeStr + ":"+str(remotePath)
        self.LogInfo("Push "+str(fileName)+" file to all Cluster Nodes")
        
        ##SUDO PUT FIX
        sudo = False
        if ("sudo" in str(self.installSudo)):
            sudo=True

        
        for node in Nodes:
            Threads.append(threading.Thread(target=self.SSHPut,args=(node.hostName,self.installUser,self.installPW,localPath,remotePath,False,sudo)))
            Threads[threadCount].daemon=True  
            Threads[threadCount].start()     
            threadCount = threadCount + 1
        for thread in Threads:
            thread.join()
            
            (hostName,username,status,results) = self.returnQueue.get()
            if (status == 0):
                self.LogInfo(str(fileName) + " File Pushed to : " + str(hostName) + " : " + str(results))
                print "        * " + str(fileName) + " File Pushed to : " + str(hostName)
            else:
                self.LogError(str(fileName) + " Could Not be Pushed to "+ str(hostName)+" : "+str(results)+" ; Exiting")
                print "        * ERROR: "+ str(fileName) + " File Could Not be Pushed to "+ str(hostName)
                pushStatus = -1
          
        return pushStatus
        
    def LocalPush(self,localPath,remotePath):    
        remoteDigest = 0
        fileExists = False
        md5 = hashlib.md5()
        with open(localPath,'rb') as f: 
            for chunk in iter(lambda: f.read(8192), b''): 
                md5.update(chunk)
        localDigest = md5.digest()
        remotePathExists = os.path.isfile(remotePath)
        if (remotePathExists):
            md5 = hashlib.md5()
            with open(remotePath,'rb') as f: 
                for chunk in iter(lambda: f.read(8192), b''): 
                    md5.update(chunk)
            remoteDigest = md5.digest()
        if (localDigest == remoteDigest):
            print "        * Copy Not Required: File Already Exists at Remote Location"
            fileExists = True
        if (not fileExists):
            filename = (localPath).split("/")[len((localPath).split("/"))-1]
            try:
                shutil.copyfile(localPath, remotePath)
                print "        * Copy  of  "+str(filename)+" Complete."
                return 0
            except Exception,err:
                self.LogError("Could Not Make Copy of File : "+str(err))
                return -1
        
    def MakeDir(self,dirName):            
        if not os.path.exists(dirName):
            os.makedirs(dirName)


    def Write(self):
        
        try:
            baseFileHandle = open (self.baseDir + "/gold/base-site.xml","r")
            goldFileHandle = open (self.goldPath,"r")
            baseData = baseFileHandle.read()
            goldData = goldFileHandle.read()
            goldFileHandle.close()
        except Exception,err:
            self.LogError("Error Reading Base XML and Gold XML:"+str(err))
        try:
            new_goldFileHandle = open(self.goldPath,"w")
            new_goldFileHandle.write(baseData+"\n")      
            new_goldFileHandle.write(goldData)
            new_goldFileHandle.close()      
            self.LogInfo("Saved new Gold XML File"+":"+str(self.xmlFilename)+":Success")
            print "        * Saved Modified Copy of "+ str(self.xmlFilename)
            return 0
        except Exception,err:
            self.LogError("Could Not Save New Version of "+ str(self.xmlFilename)+":"+str(err))
            print "        * ERROR: Could Not Save New Version of "+ str(self.xmlFilename())
            return -1
                   
    
   

    def __init__(self):

        
        Base.__init__(self)
      
      
    
